#-----------------------------------------------------
#List Databases and Tables
#-----------------------------------------------------

Import-Module SQLPS -DisableNameChecking

#current server name
$servername = "ROGUE"

$server = New-Object "Microsoft.SqlServer.Management.Smo.Server" $servername
$server.databases.Count

#create empty array
$result = @()
$server.Databases |
Where IsSystemObject -eq $false |
ForEach-Object {
    $db = $_
    $object = [PSCustomObject] @{
       Name          = $db.Name
       CreateDate    = $db.CreateDate
       RecoveryModel = $db.RecoveryModel
       NumTables     = $db.Tables.Count
       NumUsers      = $db.Users.Count
       NumSP         = $db.StoredProcedures.Count
       NumUDF        = $db.UserDefinedFunctions.Count
    }    
}
$result |
Format-Table -AutoSize


#-----------------------------------------------------
# Get properties
#-----------------------------------------------------
$server.Databases | 
Get-Member |
Where MemberType eq "Property"



#-----------------------------------------------------
# Get Methods
#-----------------------------------------------------
$server.Databases | 
Get-Member |
Where MemberType eq "Method"
 



#-----------------------------------------------------
# List Database Files and Filegroups
#-----------------------------------------------------
Import-Module SQLPS -DisableNameChecking

#current server name
$servername = "ROGUE"

$server = New-Object "Microsoft.SqlServer.Management.Smo.Server" $servername

$result = @()

$server.Databases |
Where IsSystemObject -eq $false |
ForEach-Object {
   $db = $_ 
   $db.FileGroups | 
   ForEach-Object {
      $fg = $_ 
      $fg.Files | 
      ForEach-Object {
         $file = $_

         $object = [PSCustomObject] @{
                Database = $db.Name 
                FileGroup = $fg.Name
                FileName = $file.FileName | Split-Path -Leaf
                "Size(MB)" = "{0:N2}" -f ($file.Size/1024)
                "UsedSpace(MB)" = "{0:N2}" -f ($file.UsedSpace/1MB)
                }
         $result += $object

      }
   }
}
$result |
Format-Table -AutoSize


#-----------------------------------------------------
# Add Files and Filegroups
#-----------------------------------------------------
$dbname = "Registration"
$db = $server.Databases[$dbname]
$fg = New-Object "Microsoft.SqlServer.Management.Smo.Filegroup" $db, "FG1"
$fg.Create()
$datafile = New-Object "Microsoft.SqlServer.Management.Smo.DataFile" $fg, "data4"
$datafile.FileName = "C:\DATA\data4.ndf"
$datafile.Create()


#-----------------------------------------------------
# Change file size
#-----------------------------------------------------
Import-Module SQLPS -DisableNameChecking

#current server name
$servername = "ROGUE"

$server = New-Object "Microsoft.SqlServer.Management.Smo.Server" $servername
$dbname = "Registration"

$db = $server.Databases[$dbname]
$fg = $db.FileGroups["FG1"]
$file = $fg.Files["data4"]
$file.Size = 2 * 1024 #2MB
$file.Alter()


#-----------------------------------------------------
# List Processes
#-----------------------------------------------------
Import-Module SQLPS -DisableNameChecking

#current server name
$servername = "ROGUE"

$server = New-Object "Microsoft.SqlServer.Management.Smo.Server" $servername

$server.EnumProcesses() |
Where IsSystem -eq $false |
Select Spid, Database, 
IsSystem, Login, Status, 
Cpu, MemUsage, Program |
Format-Table -AutoSize


#-----------------------------------------------------
# Check enabled features
#-----------------------------------------------------
Import-Module SQLPS -DisableNameChecking

#current server name
$servername = "ROGUE"

$server = New-Object "Microsoft.SqlServer.Management.Smo.Server" $servername

$server | 
Select IsClustered, ClusterName, 
FilestreamLevel,
IsFullTextInstalled,
LinkedServers,
IsHadrEnabled,
AvailabilityGroups




#-----------------------------------------------------
# Script Database Objects
#-----------------------------------------------------
Import-Module SQLPS -DisableNameChecking

#current server name
$servername = "ROGUE"

$server = New-Object "Microsoft.SqlServer.Management.Smo.Server" $servername

$dbname = "Chinook"
$db = $server.Databases[$dbname]

$script = New-Object "Microsoft.SqlServer.Management.Smo.Scripter" $server 
$scriptOptions = New-Object "Microsoft.SqlServer.Management.Smo.ScriptingOptions"
$scriptOptions.AllowSystemObjects = $false 
$scriptOptions.DriAll = $true 
$scriptOptions.ToFileOnly = $true 
$script.Options = $scriptOptions 

$smoObjects = @()
$filename = "C:\DATA\$($dbname)_tables_export.txt"
$script.Options.FileName = $filename

$db.Tables |
Where IsSystemObject -eq $false |
Foreach-Object {
   $smoObjects += $_
}
$script.Script($smoObjects)





#-----------------------------------------------------
# Detach a database
#-----------------------------------------------------
Import-Module SQLPS -DisableNameChecking

#current server name
$sourcename = "ROGUE"
$sourceserver = New-Object "Microsoft.SqlServer.Management.Smo.Server" $sourcename

$dbname = "Chinook"
$sourceserver.DetachDatabase($dbname, $true, $true)



#-----------------------------------------------------
# Attach a database
#------------------Import-Module SQLPS -DisableNameChecking

#current server name
$destinationname = "ROGUE\SQL2014"
$destinationserver = New-Object "Microsoft.SqlServer.Management.Smo.Server" $destinationname
$destinationserver.Name

$dbname = "Chinook"
$mdf = "C:\DATA\Chinook.mdf"
$dbowner = "QUERYWORKS\gon"

#this is where we will store all primary, secondary
#and log file information
$files = New-Object System.Collections.Specialized.StringCollection 

#assuming we need the attach process to point to 
#a different path than whats stored in the mdf
#we can specify a data path, and rebuild all the
#paths before we store in our collection
$datapath = "C:\DATA"

#collect all data file information 
$sourceserver.EnumDetachedDatabaseFiles($mdf) | 
ForEach-Object {
   #update location of file to new path
   $newfile = Join-Path $datapath (Split-Path $_ -Leaf)
   $files.Add($newfile)
}

#collect all log file information
$destinationserver.EnumDetachedLogFiles($mdf) | 
ForEach-Object {
   #update location of file to new path
   $newfile = Join-Path $datapath (Split-Path $_ -Leaf)
   $files.Add($newfile)
}
$destinationserver.AttachDatabase($dbname, $files) 
-----------------------------------



#-----------------------------------------------------
# Backup
#-----------------------------------------------------
Import-Module SQLPS -DisableNameChecking

#current server name
$servername = "ROGUE"

#$server = New-Object "Microsoft.SqlServer.Management.Smo.Server" $servername

$dbname = "Chinook"
$currdate = Get-Date -Format yyyyMMddHHmmss
$backupfolder = "C:\BACKUP\"

#generate backup file path and name
$fullbackupfilename = "$($dbname)_Full_$($currdate).bak"
$fullbackupfile = Join-Path $backupfolder $fullbackupfilename

#example filename that gets generated is:
#C:\BACKUP\Chinook_Full_20141023235306.bak

Backup-SqlDatabase -ServerInstance $servername -Database $dbname -BackupFile $fullbackupfile -Checksum -Initialize -BackupSetName "$dbname Full Backup" 

Write-Output "Database has been backed up $fullbackupfile"




#-----------------------------------------------------
# Restore Database
#-----------------------------------------------------
Import-Module SQLPS -DisableNameChecking

#current server name
$servername = "ROGUE"

$backupfile = "C:\BACKUP\Chinook_Full_20141023235841.bak"

$dbname = "Chinook"
$backupfile = "C:\BACKUP\Chinook_Full_20141023235841.bak"
Restore-SqlDatabase -Database $dbname -ReplaceDatabase -ServerInstance $servername -BackupFile $backupfile -NoRecovery



#-----------------------------------------------------
# List indexes and fragmentation
#-----------------------------------------------------
Import-Module SQLPS -DisableNameChecking

#current server name
$servername = "ROGUE"

$server = New-Object "Microsoft.SqlServer.Management.Smo.Server" $servername
$dbname = "Chinook"

$result = @()

$db = $server.Databases[$dbname]
$db.Tables | 
ForEach-Object {
   $table = $_ 
   $table.Indexes |
   Sort-Object -Property Name |
   ForEach-Object {
      $index = $_ 
      $frag = $index.EnumFragmentation()
       
      $object = [PSCustomObject] @{
         Table = $table.Name 
         Index = $index.Name
         Type = $frag.IndexType 
         Pages = $frag.Pages 
         "AvgFragmentation %" = "{0:N2}" -f ($frag.AverageFragmentation)
         "SpaceUsed(KB)" = $index.SpaceUsed

      }
        $result += $object
   }
}
$result |
Format-Table -AutoSize



#-----------------------------------------------------
# List logins and roles
#-----------------------------------------------------
Import-Module SQLPS -DisableNameChecking

#current server name
$servername = "ROGUE"

$server = New-Object "Microsoft.SqlServer.Management.Smo.Server" $servername

$result = @()

$server.Logins |
Where IsSystemObject -EQ $false |
ForEach-Object {
   $login = $_
   $object = [pscustomobject] @{
      Login = $login.Name
      LoginType = $login.LoginType
      CreateDate = $login.CreateDate
      ServerRoles = $login.ListMembers()
   }
   $result += $object
}
$result |
Format-Table -AutoSize



#-----------------------------------------------------
# Check orphaned users
#-----------------------------------------------------
Import-Module SQLPS -DisableNameChecking

#current server name
$servername = "ROGUE"

$server = New-Object "Microsoft.SqlServer.Management.Smo.Server" $servername

$result = @()
$server.Databases |
Where IsSystemObject -EQ $false |
ForEach-Object {
    $db = $_ 
    $db.Users |
    Where IsSystemObject -eq $false |
    ForEach-Object {
        $dbuser = $_
        $object = [PSCustomObject] @{
        Database = $db.Name 
        DBUser = $dbuser.Name
        Orphaned = if ($dbUser.UserType -eq "NoLogin") {"Yes"} else {"No"}
        Login = $dbuser.Login
        LoginType = $dbUser.LoginType
        }
  $result += $object
    }
}
$result |
Format-Table -AutoSize



#-----------------------------------------------------
# List permissions
#-----------------------------------------------------
Import-Module SQLPS -DisableNameChecking

#current server name
$servername = "ROGUE"

$server = New-Object "Microsoft.SqlServer.Management.Smo.Server" $servername

$result = @()
$server.Databases |
Where IsSystemObject -EQ $false |
Where Name -eq "Chinook" |
ForEach-Object {
    $db = $_ 
    $db.Users |
    Where IsSystemObject -eq $false |
    ForEach-Object {
        $dbuser = $_

        $object = [PSCustomObject] @{
        Database = $db.Name 
        DBUser = $dbuser.Name
        Orphaned = if ($dbUser.UserType -eq "NoLogin") {"Yes"} else {"No"}
        Login = $dbuser.Login
        LoginType = $dbUser.LoginType
        DBRoles = $dbuser.EnumRoles()
        ObjectPermissions  = ($db.EnumObjectPermissions($dbuser.Name) | SELECT @{N="P";E={$_.ObjectName + " " + $_.PermissionState + " " + $_.PermissionType  }} )
        }
  $result += $object
    }
}
$result |
Format-List


#-----------------------------------------------------
# Add Login
#-----------------------------------------------------
Import-Module SQLPS -DisableNameChecking

#current server name
$servername = "ROGUE"

$server = New-Object "Microsoft.SqlServer.Management.Smo.Server" $servername

$loginname = "kurapika"

#for this example, we will check if login exists
#and if it does we will drop it
if ($server.Logins.Contains($loginname))
{
   $server.Logins[$loginname].Drop()
}

$login = New-Object "Microsoft.SqlServer.Management.Smo.Login" $server, $loginname 
$login.LoginType = [Microsoft.SqlServer.Management.Smo.LoginType]::SqlLogin
$login.PasswordExpirationEnabled = $false 

#prompt for password
$password = Read-Host "Password: " -AsSecureString
$login.Create($password)

#add to server roles 
$server.Logins[$loginname].AddToRole("dbcreator")


#-----------------------------------------------------
# Add database user
#-----------------------------------------------------
#add database mapping 
$dbname = "Chinook"
$dbusername = "kurapika"
$db = $server.Databases[$dbname]

if ($db.Users.Contains($dbusername))
{
   $db.Users[$dbusername].Drop()
}

$dbuser = New-Object "Microsoft.SqlServer.Management.Smo.User" $db, $dbusername
$dbuser.Login = $loginname
$dbuser.Create()

#add database role
$db.Roles["db_datareader"].AddMember($dbuser.Name)


#initial permission is View Definition
$permissionset = New-Object "Microsoft.SqlServer.Management.Smo.ObjectPermissionSet" ([Microsoft.SqlServer.Management.Smo.ObjectPermission]::ViewDefinition)

#add additional permission: Alter
$permissionset.Add([Microsoft.SqlServer.Management.Smo.ObjectPermission]::Alter)

#add permission set to view vwAlbums
$db.Views["vwAlbums"].Grant($permissionset, $dbuser.Name)


#-----------------------------------------------------
# List job details
#-----------------------------------------------------
Import-Module SQLPS -DisableNameChecking

#current server name
$servername = "ROGUE"

$server = New-Object "Microsoft.SqlServer.Management.Smo.Server" $servername

$result = @()

$server.JobServer.Jobs | 
Foreach-Object {
   $job = $_
   $job.JobSteps | 
   ForEach-Object {
      $jobstep = $_
      $object = [PSCustomObject] @{
          Name = $job.Name 
          LastRunDate = $job.LastRunDate
          LastRunOutcome = $job.LastRunOutcome
          Step = $jobstep.Name
          LastStepOutcome = $jobstep.LastRunOutcome
       }
       $result += $object      
   }
}

$result |
Format-Table 



#-----------------------------------------------------
#
#-----------------------------------------------------


#-----------------------------------------------------
#
#-----------------------------------------------------


#-----------------------------------------------------
#
#-----------------------------------------------------
